/*
    This file is part of Raptor.

    Raptor is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Raptor is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Raptor.  If not, see <http://www.gnu.org/licenses/>.

 */

#ifndef __XMLURLCONTAINER_H__
#define __XMLURLCONTAINER_H__

#include <QObject>
#include <QHttp>
#include <QNetworkProxy>
#include <QUrl>
#include <QDomDocument>
#include <QTemporaryFile>
#include <QPointer>

class xmlUrlContainer : public QObject
{
	Q_OBJECT

	public:

		enum E_ERROR
		{
			ERROR_NONE,
			ERROR_HTTP,
			ERROR_XML,
		};

		enum E_STATE
		{
			STATE_FINISHED,
			STATE_ERROR,
			STATE_XML_LOADED,
		};

		enum E_TYPE
		{
			TYPE_NO_FOUND,
			TYPE_OPEN_URL,
			TYPE_METHOD_GET,
			TYPE_METHOD_POST,
			TYPE_REGEXP,
			TYPE_DUMMY,
			TYPE_STEP,
			TYPE_DO_STEP,
			TYPE_GENERATE_LINK,
			TYPE_CAPTCHA,
			TYPE_LOAD_CAPTCHA,
			TYPE_FROM_CAPTCHA,
			TYPE_MULTI_REGEXP,
			TYPE_FORM_POST,
			TYPE_FOR_I_IN,
			TYPE_APPEND,
			TYPE_RETURN,
			TYPE_HEADER,
			TYPE_WAIT_HTTP,
			TYPE_REGISTER_VAR,
			TYPE_SUB_ACTION,
			TYPE_FINISH,
			TYPE_ADD_PROGRESS,
			TYPE_GENERATE_STR,
			TYPE_FROM_UNICODE,
		};

		struct S_HOSTER
                {
			QString name;
			QString file;
                        QRegExp regExp;
                        QRegExp regExp2;
                        bool allowOtherHostnames;

                        S_HOSTER(QString const& _name, QString const& _file, QRegExp const& _regExp,  QRegExp const& _regExp2,  bool const& _allowOtherHostnames) :
                                name(_name),
                                file(_file),
                                regExp(_regExp),
                                regExp2(_regExp2),
                                allowOtherHostnames(_allowOtherHostnames)
                                { }
		};

		struct S_WAITFOR
		{
			QDomNode node;
			int it;

			S_WAITFOR(const QDomNode &n, int i)
			{
				node = n;
				it = i;
			}
		};

		xmlUrlContainer();
		~xmlUrlContainer();

		void setCaptchaDir(const QString &dir);
		void setXmlDir(const QString &dir);
                void setProxy(QNetworkProxy const &proxy);
		void start();

		bool loadXmlForLink(const QString &DownloadLink, const QString &folder = "");
		void submitCaptcha(const QString &str);

                QList<QPair<QPair<QRegExp, bool>, QRegExp> > getRexExpList();

		QString fromUnicode(const QString &str);
		QString getVar(const QString &var);

	public slots:

	signals:

		void finished(const QStringList &urlList, const bool &error);
		void captcha(const QString &file);
		void stateChanged();
		void progressChanged(const int &progress);

	private:

		bool verbose;

		QHttp http;
		QByteArray response;
		QString page;
		int waitingId;

		E_ERROR m_error;
		E_STATE m_state;

		double progress;

		int hoster;
		QDomDocument domHoster;
		int step;

		bool reinitLoop;
		bool waitForHttp;
		int waitInsertAt;
		QList<S_WAITFOR> waitHttp;

		QPointer<QTemporaryFile> captchaFile;

		QList<S_HOSTER> validLinksList;

		QString captchaDir;
		QString captchaReturn;
		QString xmlDir;

		QString url;
		QMap<QString, QString> regExpResults;
		QMap<QString, QStringList> regExpListResults;

		void setState(const E_STATE &state);
		bool loadXmlFile(const QString &xmlFile);
		void loadAvailabelHoster(const QString &folder);

		void doStep();
		int parseType(const QString &type);
		void doAction(const QDomNode &parent, const int startI=0);
		void switchAction(const QDomNode &action);
		bool switchResult(const QDomNode &result);

		bool checkAttributes(const QDomNode &node, const QStringList &attributes);

		void addVar(const QString &key, const QString &value);

	private slots:

		void slot_http_requestFinished(int id, bool error);
		void slot_http_readyRead(const QHttpResponseHeader & resp);
		void slot_http_sslErrors(const QList<QSslError> & errors);
};

#endif
